iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
自我挑戰組

30天CSS、JS、React打造專案零組件系列 第 20

DAY20 - [JS] 小結與番外篇:淺拷貝 與 深拷貝

  • 分享至 

  • xImage
  •  

今日文章目錄

  • 番外篇:淺拷貝
  • 番外篇:深拷貝
  • 小結

ToDoList + 番茄鐘時間管理,整體上練習到一段落了。今天JS練習來個番外篇:紀錄目前學到的淺拷貝與深拷貝方法。


事前準備

在進行之前,要對 基礎型別primitive value 與 物件型別reference value有基本認識:

  • 基礎型別: string number boolean null undefined symbol
  • 物件型別: 除了基礎型別以外,舉凡 物件 函式 等。

兩者在賦值上的差別:

基礎型別: pass by value

```
    let a = 10;
    let b = a;
    a = 1000;
    console.log("a: ", a);  // a:  1000
    console.log("b: ", b);  // b:  10
```
  • 以上範例可以看到,b複製a的值到自己的變數容器裡,所以當a重新賦值,b並不受影響。
    基礎型別: pass by value

物件型別: pass by reference

```
    let c = {id: 1, name: "Joanna"};
    let d = c;
    c.name = "David";
    console.log("c: ", c);  // c: {id: 1, name: "David"}
    console.log("d: ", d);  // d: {id: 1, name: "David"}
```
  • 以上範例可以看到,d指向與c相同的位址,所以當c重新賦值,代表相同位址的值更新,d一同受影響。
    物件型別: pass by reference

使用時機

當我們取得資料如下方,如果我們要針對資料進行修改,但又不想動到原本資料時,我們可以怎麼做呢?
通常會拷貝一份,在拷貝資料上進行修改,但可能會碰到 淺拷貝 與 深拷貝的坑,也就是今天要練習的部分。

const info = [
    "David", 
    false, 
    {
        name: "Joanna", 
        hobbies:["Coding", "Cooking"]
    }
];
const details = {
    id: 1,
    name: "Anna",
    contact:{
        phone: 0912345678,
        country: "Taiwan",
        hasVaccinated: true
    }
};

番外篇:淺拷貝

  1. slice(start, beforeEnd):
    • 作用對象:陣列。
    • 用途:依據作用陣列,指定起始與結束索引,複製一新陣列。
    • 參數:start 起始索引,beforeEnd 結束索引以前。如果沒有指定,會全部複製作用陣列。
    • 回傳值:全新陣列。
    • 會改變作用陣列:不會。
      slice(start, beforeEnd)驗證
  2. Object.assign(target obj, resource1, resource2, ...)
    • 作用對象:物件target obj
    • 用途:將多組物件合併成一組。
    • 參數:
      • target obj: 作用物件
      • resource1... : 要合併的來源物件,多組的話依 ,隔開
    • 回傳值:回傳合併完的 target obj
    • 會改變作用物件:會。
      Object.assign(target obj, resource1, resource2, ...)驗證
  3. [...array] {...obj} : spread operator
    • 重新建立新容器,內容從指定陣列或物件複製。
    • 舊內容,新容器:
      也就是說內容會依據 基礎型別(copy by value) 或 物件型別(copy by reference)類型進行複製,屬於物件型別的內容在修改的時候,更新指向位址的值,所有指向相同位址的其他內容也同時更新。
      array spread operator 驗證
      obj spread operator 驗證

番外篇:深拷貝

  • JSON.stringify() -> JSON.parse()

小結

在啟動10天JS練習計劃時,原本希望10天都練習到不同的功能。但在實際執行的時候,發現自己在練習ToDoList基本操作遇到一些坑,考量時間分配與自己能力情況下,選擇好好把一個專項拆分成很小的項目,讓這十天都有一點小進步。透過每天紀錄,坦白說我每天都在擔心產出,但還是得到一些收穫:實際執行跟學會JS還是有很大的差距,抓緊努力練了,我要變強!!!

撐過20天的大家,可以開始倒數囉


上一篇
DAY19 - [JS] 功能擴充 - 紀錄花費時間
下一篇
DAY21 - [React] 建立專案,基礎設定
系列文
30天CSS、JS、React打造專案零組件30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言